home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / cycles / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  15.1 KB  |  584 lines

  1. /*
  2.  * cycles
  3.  *
  4.  *    by Robin Humble <rjh@pixel.maths.monash.edu.au>
  5.  *       Alan Lipton  <alan.j.lipton@eng.monash.edu.au>)
  6.  *       Nick Fitton  <jalippo@pixel.maths.monash.edu.au>
  7.  */
  8.  
  9. #include <stdio.h>    /* for printf, sprintf, cuserid, ... */
  10. #include <bstring.h>    /* for bcopy */
  11. #include <unistd.h>    /* for sleep */
  12. #include <sys/types.h>    /* for times */
  13. #include <sys/times.h>    /* for times */
  14. #include <sys/param.h>    /* for times */
  15. #include <stdlib.h>    /* @@@ tmp for getenv */
  16. #include <string.h>    /* @@@ tmp for strcmp */
  17. #include <gl/device.h>
  18. #include "cycles.h"
  19. #ifdef AUDIO
  20. #include "sound.h"
  21. short kaboom, boom[CYCLES], still_close, tumbling;
  22. #endif
  23.  
  24. Matrix idmat = {1.0, 0.0, 0.0, 0.0,
  25.                 0.0, 1.0, 0.0, 0.0,
  26.                 0.0, 0.0, 1.0, 0.0,
  27.                 0.0, 0.0, 0.0, 1.0};
  28.  
  29. Pattern16 quartertone = {0x8888, 0x2222, 0x4444, 0x1111, 0x8888, 0x2222,
  30.                          0x4444, 0x1111, 0x8888, 0x2222, 0x4444, 0x1111,
  31.                          0x8888, 0x2222, 0x4444, 0x1111};
  32.  
  33. /* This is a direction vector in (x,z) coordinates */
  34. float vec[4][2] = { { 0.0, -1.0},
  35.                     {-1.0,  0.0},
  36.                     { 0.0,  1.0},
  37.                     { 1.0,  0.0} };
  38.  
  39.  
  40. float speed_fac;    /* for real-timing */
  41. CYCLE *good, bike[CYCLES];
  42. int used[CYCLES];   /* true if this slot filled in user list */
  43. int robot[CYCLES];  /* list of robots running on this machine */
  44. int solo, in_win, wheel_angle[CYCLES][2], neo_mort[CYCLES];
  45. int audio, demo_mode;
  46. clock_t last_sent;
  47. POINT up_hole[LEVELS], down_hole[LEVELS];
  48. extern CYCLE start_pos[CYCLES];
  49.  
  50.  
  51. /*
  52.  * main routine - this routine initializes the game, polls the input
  53.  * devices, calls the moving routines and draws the scenery.
  54.  */
  55. int main (int argc, char **argv) {
  56.     int i, start_again, new_arrived, close_id, pts, total_pts, games;
  57.     int help_mode, look_offset, num_robots, next_level;
  58.     int big_kills, trail_kills, tot_big_kills, tot_trail_kills;
  59.     int colour_choice;
  60.     short val;
  61.     long event;
  62.     struct tms t;
  63.     float min;
  64.     char name[NAME_SIZE];
  65. #ifdef DEBUG
  66.     int remote;
  67. #endif
  68. #ifdef SHOW_TIMING
  69.     double frame_time;
  70.     int frame_count, frame_ave = 5;
  71.     clock_t prev_ticks, now_ticks;
  72. #endif
  73.  
  74.     /* parse networking args */
  75.     parse_args(argc, argv);
  76.  
  77.     solo = 0;
  78.     demo_mode = 0;
  79. #ifdef AUDIO
  80.     audio = 1;
  81. #else
  82.     audio = 0;
  83. #endif
  84.     num_robots = 2;
  85.     colour_choice = -1;
  86.     if (num_robots > CYCLES-1) num_robots = CYCLES-1;
  87.  
  88.     total_pts = 0;
  89.     tot_big_kills = 0;
  90.     tot_trail_kills = 0;
  91.     games = 0;
  92.     help_mode = 0;
  93.     speed_fac = 1.0;
  94.     for (i = 0; i < CYCLES; i++) {
  95.     wheel_angle[i][0] = 0;
  96.     wheel_angle[i][1] = 0;
  97.     }
  98.     bcopy(cuserid((char *)NULL), name, NAME_SIZE);
  99.  
  100.     init_fonts();
  101.  
  102. #ifdef DEBUG
  103. foreground();    /* @@@ */
  104. /* prefposition(300, 1100, 400, 800); */
  105. #endif
  106.  
  107.     openwindow();
  108.  
  109.     srand((unsigned int)times(&t)); /* seed random numbers */
  110.     make_objs();
  111.     defpattern(1, 16, quartertone);
  112.     in_win = 1;    /* assume have input focus */
  113.  
  114.     title_screen(0, name, &colour_choice, &num_robots);
  115.     scale_fonts_to_win();
  116.     title_screen(1, name, &colour_choice, &num_robots);
  117.     title_screen(2, name, &colour_choice, &num_robots);
  118.     title_screen(3, name, &colour_choice, &num_robots);
  119.     title_screen(4, name, &colour_choice, &num_robots);
  120.     if (!solo) title_screen(5, name, &colour_choice, &num_robots);
  121.  
  122. #ifdef DEBUG
  123. /* @@@ */
  124. if (solo)
  125.   printf("solo, cycles: %d\n", num_robots);
  126. else
  127.   printf("network!!! cycles: %d\n", num_robots);
  128. if (audio) printf("AUDIO!!!\n");
  129. #endif
  130.  
  131.     if (!solo) init_comms();
  132.     init_holes();
  133. #ifdef AUDIO
  134.     if (audio) {
  135.     init_audio();
  136.     init_sound_flags();
  137.     }
  138. #endif
  139.  
  140.     if (solo) {
  141.     /* init us -> id = 0 */
  142.     good = &bike[0];
  143.     init_pos(good);
  144.     good->id = 0;
  145.     used[0] = 1;
  146.  
  147.     /* and our robots */
  148.     for (i = 1; i <= num_robots; i++) {
  149.         robot[i] = 1;
  150.         do {    /* loop 'til get different colour */
  151.         init_pos(&bike[i]);
  152.         } while (bike[i].trail_colour == good->trail_colour);
  153.         bike[i].id = i;
  154.         used[i] = 1;
  155.         bike[i].owner = good->id;
  156.         init_tumble(&bike[i]);
  157.     }
  158.     }
  159.     else {
  160.     init_network(&num_robots);  /* <- includes setting up our */
  161.                                     /*    position and our robots */
  162.  
  163.     /* send a dead, but entering packet */
  164.     good->alive = 0;
  165.     for (i = 0; i < CYCLES; i++)
  166.         if (robot[i]) bike[i].alive = 0;
  167.  
  168.     /* wait for network replies to our entry to the grid */
  169.     send_update_mcast();
  170.     last_sent = times(&t);
  171.     new_arrived = wait_for_replies();
  172.  
  173.     /* make us alive again */
  174.     good->alive = 1;
  175.     good->owner = good->id;
  176.     for (i = 0; i < CYCLES; i++)
  177.         if (robot[i]) {
  178.         bike[i].alive = 1;
  179.         bike[i].owner = good->id;
  180.         init_tumble(&bike[i]);
  181.         send_full_mcast(&bike[i]);
  182.         }
  183.     }
  184.  
  185. #ifdef DEBUG
  186. /* @@@ */
  187. if (demo_mode) printf("demo mode! %d\n", robot[good->id]);
  188.  
  189. /* @@@ tmp hack for dgl -- how do we do this properly??? */
  190. remote = 0;
  191. if (strcmp(getenv("DISPLAY"), ":0")) remote = 1;
  192. if (remote) printf("displaying REMOTE!\n");
  193. #endif
  194.  
  195.     while (1) {
  196.  
  197.     start_again = 1;
  198.  
  199.     /* setup tumble initial state */
  200.     do {    /* loop until we're not gonna immediately hit */
  201.         init_pos(good);
  202.     } while (fall_down_hole(good) == -1 && block(good->id, good->origin.x, good->origin.z, good->vec_ptr, &close_id) - CYCLE_NOSE < 3.0*good->step);
  203.     if (demo_mode) {
  204.         good->type = ROBOT;
  205.         robot[good->id] = 1;
  206.     }
  207.     else {
  208.         good->type = PERSON;
  209.     }
  210.     sprintf(good->name, "%s", name);
  211.     good->pts = total_pts;
  212.     good->games = games;
  213.     if (colour_choice != -1) good->trail_colour = colour_choice;
  214.     init_tumble(good);
  215.  
  216.     /* send all our init info */
  217.     if (!solo) send_full_mcast(good);
  218.  
  219. #ifdef DEBUG
  220. printf("TOP CYC cycles: robot: \n");
  221. { int i; for (i=0;i<CYCLES;i++) printf("%d ", robot[i]); }
  222. printf("\n");
  223. printf("cycles: used: \n");
  224. { int i; for (i=0;i<CYCLES;i++) printf("%d ", used[i]); }
  225. printf("\n");
  226. printf("cycles: PLAYERS: \n");
  227. { int i; for (i=0;i<CYCLES;i++) if (used[i]) printf("%d: %s ", bike[i].id, bike[i].name); }
  228. printf("\n");
  229. #endif
  230.  
  231.     look_offset = 0;
  232.     pts = 0;
  233.     big_kills= 0;
  234.     trail_kills = 0;
  235.     for (i = 0; i < CYCLES; i++) neo_mort[i] = 0;
  236.     min = 2.0*DIM;
  237.  
  238.     search_for_exit();  /* leave now if requested */
  239.  
  240.     do {   /* loop here until die */
  241.  
  242. #ifdef DEBUG
  243. printf("\n");
  244. printf("top cycles: robot: \n");
  245. { int i; for (i=0;i<CYCLES;i++) printf("%d ", robot[i]); }
  246. printf("\n");
  247. printf("top cycles: used: \n");
  248. { int i; for (i=0;i<CYCLES;i++) printf("%d ", used[i]); }
  249. printf("\n");
  250. printf("top cycles: players: \n");
  251. { int i; for (i=0;i<CYCLES;i++) if (used[i]) printf("%d: %s aliv? %d fall %g   ",
  252.  bike[i].id, bike[i].name, bike[i].alive, bike[i].fall); }
  253. printf("\n");
  254. #endif
  255.  
  256.         /* set the speed_fac for this frame, guess if first */
  257.         set_speed_fac(start_again);
  258.  
  259. #ifdef SHOW_TIMING
  260.         if (start_again) {
  261.             frame_time = 0.0;
  262.         frame_count = 0;
  263.         prev_ticks = times(&t);
  264.         }
  265.         else
  266.         frame_count++; frame_count %= frame_ave;
  267. #endif
  268.         start_again = 0;
  269.  
  270.         /* handle buffered turn events */
  271.         if (!demo_mode) {
  272.         if (good->lturn > 0) good->lturn--;
  273.         if (good->rturn > 0) good->rturn--;
  274.  
  275.         /* if turn > 0 then we have a buffered turn */
  276.         if (good->lturn && !good->rturn) turn(good, 1.0);
  277.         if (good->rturn && !good->lturn) turn(good, -1.0);
  278.         }
  279.  
  280.         /* take user input sequence */
  281.         while (qtest()) {
  282.         switch(event = qread(&val)) {
  283.         case SPACEKEY:
  284.             if (val && !good->jump) {
  285.             jump(good);
  286. #ifdef AUDIO
  287.             if (audio) play_sound("jump.aiff");
  288. #endif
  289.             }
  290.             break;
  291.         case LEFTMOUSE:
  292.             if (val && good->falling == 0 && !good->jump && !demo_mode) {
  293.             if (!good->lturn && !good->rturn) turn(good, 1.0);
  294.             good->lturn++;
  295.             }
  296.             break;
  297.         case RIGHTMOUSE:
  298.             if (val && good->falling == 0 && !good->jump && !demo_mode) {
  299.             if (!good->lturn && !good->rturn) turn(good, -1.0);
  300.             good->rturn++;
  301.             }
  302.             break;
  303.         case LEFTARROWKEY:
  304.             if (val) {
  305.             look_offset++;
  306.             if (look_offset == 4) look_offset = 0;
  307.             }
  308.             break;
  309.         case RIGHTARROWKEY:
  310.             if (val) {
  311.             look_offset--;
  312.             if (look_offset == -1) look_offset = 3;
  313.             }
  314.             break;
  315.         case ESCKEY:    /* NOTE: this in search_for_exit and draw_score_screen also */
  316.             good->quit = 1;
  317.             for (i = 0; i < CYCLES; i++)
  318.             if (robot[i]) bike[i].quit = 1;
  319.             if (!solo) send_update_mcast();
  320. #ifdef AUDIO
  321.             if (audio) close_audio();
  322. #endif
  323.             exit(0);
  324.             break;
  325.         case HKEY:
  326.             if (val) {
  327.             help_mode++;
  328.             help_mode %= 2;
  329.             }
  330.             break;
  331.         case REDRAW:
  332.             reshapeviewport();
  333.             break;
  334.         case INPUTCHANGE:
  335.             in_win = val % 256;        /* % for dgl stuff */
  336.             break;
  337.         default:
  338.             printf("unhandled default event: %ld\n", event);
  339.             break;
  340.         }
  341.         }   /* end of input queue */
  342.  
  343.         /* speed up and slow down */
  344.         if (!demo_mode && good->falling == 0 && !good->jump) { /* fall things are pre-programmed and can't accel when jumped! */
  345.         if (in_win && (getbutton(MIDDLEMOUSE) || getbutton(AKEY)))
  346.             good->step += 0.1*speed_fac;
  347.         else
  348.             good->step -= 0.2*speed_fac;
  349.  
  350.         /* set min and max speeds */
  351.         if (good->step < MIN_STEP)
  352.             good->step = MIN_STEP;
  353.         else if (good->step > MAX_STEP)
  354.             good->step = MAX_STEP;
  355.         }
  356. #ifdef AUDIO
  357.         if (audio) change_cycle_pitch(min);
  358. #endif
  359.  
  360. #ifdef DEBUG
  361. printf("\n\npre-die: alive %d, step %g, oy %g, ht %g\n", 
  362.  good->alive, good->step, good->origin.y, (HEIGHT + TRAIL_HEIGHT));
  363.  
  364. printf("after input cycles: players: good->fall %g \n", good->fall);
  365. { int i; for (i=0;i<CYCLES;i++) if (used[i]) printf("%d: %s aliv? %d  ", bike[i].id, bike[i].name, bike[i].alive); }
  366. printf("\n");
  367. #endif
  368.         /*
  369.          * network - read others positions
  370.          * still read the network, even when doing fall things...
  371.          */
  372.         if (!solo) new_arrived = get_and_sort_mcasts();
  373.  
  374. #ifdef DEBUG
  375. printf("after get mcast cycles: players: good->fall %g \n", good->fall);
  376. { int i; for (i=0;i<CYCLES;i++) if (used[i]) printf("%d: %s aliv? %d  ", bike[i].id, bike[i].name, bike[i].alive); }
  377. printf("\n");
  378. #endif
  379.  
  380.         if (!demo_mode && good->falling == 0) {
  381.         /* start a die if we'll hit anything */
  382.         if (((min = (block(good->id, good->origin.x, good->origin.z, good->vec_ptr, &close_id) - CYCLE_NOSE)) <= good->step*speed_fac)
  383.           && (good->origin.y <= (HEIGHT + TRAIL_HEIGHT))) {
  384.             good->fall += speed_fac;
  385.             good->falling++;
  386.             good->who_we_hit = close_id;
  387.         }
  388.         /* also check if we made it ouside by mistake and fall if we did */
  389.         check_outside(good);
  390.  
  391.         /* see if we've fallen down a hole */
  392.         if ((next_level = fall_down_hole(good)) != -1)
  393.             new_level(good, next_level);
  394.  
  395.         /* move us... */
  396.         mov(good);
  397.         }
  398.  
  399.  
  400.         /* move the bikes and let them avoid */
  401.         for (i = 0; i < CYCLES; i++)
  402.         if (robot[i] && bike[i].falling == 0)
  403.             move_cycles(&bike[i]);
  404.  
  405.         /* sort out our motion */
  406.         if (!demo_mode) {
  407.         if (good->falling == 0) {
  408. #ifdef AUDIO
  409.             tumbling = 0;
  410. #endif
  411.             calcorg(good); /* handle jumping */
  412.         }
  413.         else if (good->falling > 0) { /* we've hit and are falling */
  414.             explode_me(good);
  415.             good->fall += speed_fac;
  416.             good->falling++;
  417. #ifdef AUDIO
  418.             if (audio && !kaboom) play_sound("boom1.aiff");
  419.             kaboom = 1;
  420. #endif
  421.         }
  422.         else { /* tumbling down onto grid */
  423.             tumble_down(good);
  424. #ifdef AUDIO
  425.             tumbling = 1;
  426.             kaboom = 0;
  427. #endif
  428.         }
  429.         }
  430.         else {  /* demo mode explode */
  431.         if (good->falling > 0) { /* we've hit and are falling */
  432.             explode_me(good);    /* incrementing fall handled in move_our_robots */
  433. #ifdef AUDIO
  434.             if (audio && !kaboom) play_sound("boom1.aiff");
  435.             kaboom = 1;
  436. #endif
  437.         }
  438.         }
  439.  
  440.         good->view = vadd(good->origin, good->direction);
  441.  
  442.         /* ooops, we died */
  443.         if (!demo_mode && good->fall >= WALL_FALL) good->alive = 0;
  444.  
  445.         /* see if we've scored any points */
  446.         if (good->falling == 0)
  447.         do_scoring(good, &pts, &big_kills, &trail_kills);
  448.  
  449.         /* network mode - send info about ourselves and our robots */
  450.         if (!solo) {
  451.         /* if we've not sent for > NET_TIMEOUT seconds then request full */
  452.         if (new_arrived || last_sent + NET_TIMEOUT*HZ < times(&t))
  453.             send_all_full_mcast();
  454.         else
  455.             send_update_mcast();
  456.  
  457.         last_sent = times(&t);
  458.         }
  459.  
  460. #ifdef DEBUG
  461. printf("after sends cycles: players: \n");
  462. { int i; for (i=0;i<CYCLES;i++) if (used[i]) printf("%d: %s aliv? %d fall %g   ",
  463.  bike[i].id, bike[i].name, bike[i].alive, bike[i].fall); }
  464. printf("\n");
  465. #endif
  466.  
  467.         /* set view */
  468.         loadmatrix(idmat);
  469.         if (good->falling == 0)
  470.         lookat(good->origin.x, good->origin.y - 0.5, good->origin.z,
  471.                good->origin.x + vec[(good->vec_ptr + look_offset)%4][0], good->origin.y - 0.5, good->origin.z + vec[(good->vec_ptr + look_offset)%4][1], 0.0);
  472.         else
  473.         lookat(good->origin.x, good->origin.y - 0.5, good->origin.z,
  474.                      good->view.x, good->origin.y - 0.5, good->view.z, 0.0);
  475.  
  476.         /* lots of drawing... */
  477. #ifdef RGB_MODE
  478.         cpack(0x0);
  479. #else
  480.         color(BLACK);
  481. #endif
  482.         clear();
  483.         zclear();
  484.  
  485.         drawgrid(good->level, look_offset);
  486.  
  487.         if (good->falling >= 0) drawtrail(good, good->level);
  488.  
  489.         /* jump, restart, draw etc our robots */
  490.         move_our_robots();
  491.  
  492. #ifdef DEBUG
  493. printf("afetr moves cycles: players: good->fall %g \n", good->fall);
  494. { int i; for (i=0;i<CYCLES;i++) if (used[i]) printf("%d: %s aliv? %d fall %g   ",
  495.  bike[i].id, bike[i].name, bike[i].alive, bike[i].fall); }
  496. printf("\n");
  497. #endif
  498.         /* draw all */
  499.         for (i = 0; i < CYCLES; i++)
  500.         if (used[i] && bike[i].alive && i != good->id && bike[i].falling >= 0)
  501.             drawtrail(&bike[i], good->level);
  502.         for (i = 0; i < CYCLES; i++)
  503.         if (used[i] && bike[i].alive && i != good->id) {
  504.             if (bike[i].falling <= 0)
  505.             drawcycle(&bike[i], good->level, look_offset);
  506.             else {
  507.             explode(&bike[i], good->level);
  508. #ifdef AUDIO
  509.             if(audio && !boom[i]) {
  510.                 if(bike[i].level == good->level)
  511.                 play_sound("boom2.aiff");
  512.                 else
  513.                 play_sound("boom3.aiff");
  514.             }
  515.             boom[i] = 1;
  516. #endif
  517.             }
  518.         }
  519.  
  520.         /* kill off any cycles that aren't talking any more */
  521.         if (!solo) kill_dead_cycle();
  522.  
  523. #ifdef DEBUG
  524. printf("after draws cycles: players: good->fall %g \n", good->fall);
  525. { int i; for (i=0;i<CYCLES;i++) if (used[i]) printf("%d: %s aliv? %d  ", bike[i].id, bike[i].name, bike[i].alive); }
  526. printf("\n");
  527. #endif
  528.         /* fade to grey if dying */
  529.         if (good->falling > 0) {
  530. #ifdef RGB_MODE
  531.         cpack(0xaaaaff);
  532. #else
  533.         color(WHITE);
  534. #endif
  535.         setpattern(1);
  536.         clear();
  537.         setpattern(0);
  538.         }
  539.  
  540.         loadmatrix(idmat);
  541.         draw_info(look_offset, help_mode, min, pts, big_kills, trail_kills);
  542.  
  543. #ifdef DEBUG
  544. printf("after info cycles: players: good->fall %g \n", good->fall);
  545. { int i; for (i=0;i<CYCLES;i++) if (used[i]) printf("%d: %s aliv? %d  ", bike[i].id, bike[i].name, bike[i].alive); }
  546. printf("\n");
  547. #endif
  548.  
  549. #ifdef SHOW_TIMING
  550.         if (!frame_count) {
  551.         now_ticks = times(&t);
  552.         frame_time = (double)(now_ticks - prev_ticks)/(double)(HZ*frame_ave);
  553.         prev_ticks = now_ticks;
  554.         }
  555.         loadmatrix(idmat);
  556.         show_time(frame_time, min);
  557. #endif
  558.  
  559.         swapbuffers();
  560.  
  561. #ifdef DEBUG
  562. /* @@@ tmp hack for dgl */
  563. if (remote && good->fall) finish();
  564. #endif
  565.  
  566.     } while (good->alive);
  567.  
  568.     total_pts += pts;
  569.     tot_big_kills += big_kills;
  570.     tot_trail_kills += trail_kills;
  571.     good->games = ++games;
  572.     good->pts = total_pts;
  573.  
  574.     if (!demo_mode) {
  575.         good->alive = 0;
  576.         score_screen(pts, tot_big_kills, tot_trail_kills);
  577.     }
  578. #ifdef DEBUG
  579. printf("\n\n");
  580. #endif
  581.     search_for_exit();
  582.     }
  583. }
  584.